﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using TookKit.Mvvm.Interfaces;

namespace TookKit.Mvvm.Extensions
{
    public static class ContainerExtension
    {
        /// <summary>
        /// 注册模块 + 初始化模块
        /// </summary>
        /// <param name="container"></param>
        /// <returns></returns>
        public static IContainer InitializeModules(this IContainer container)
        {

            //第一步，模块自动加载和注册
            container.ModuleManager.InitializeModules();

            //第二步，实例化所有模块，并运行模块中的RegisterTypes方法
            var moduleMaps = container.ModuleManager.ModuleMaps;
            var instances = container.ModuleManager.Instances;
            foreach (var module in moduleMaps)
            {
                Type moduleType = module.Value;
                if (!instances.ContainsKey(moduleType.FullName))
                {
                    object instance = Activator.CreateInstance(moduleType);//实例化模块
                    instances.TryAdd(moduleType.FullName, instance);
                    var methodInfo = instance.GetType().GetMethod("RegisterTypes");
                    methodInfo?.Invoke(instance, new object[] { container });//执行RegisterTypes方法，注册该模块下的类型
                }
            }

            //第三步，自动注册子模块所在程序集的类型（条件：标注DependencyInjectionAttribute特性）
            foreach (Type moduleType in moduleMaps.Values)
            {
                //获取模块所在的程序集
                Assembly assembly = moduleType.Assembly;
                //获取所有被标识为DependencyInjectionAttribute特性的类型的Type
                List<Type> types = assembly.GetDependencyInjectionTypes();
                //注册这些类型
                container.Register(types);
            }

            return container;
        }
    }
}
